﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Objects;
using System.Data.Objects.DataClasses;

namespace EntityFrameworkContrib.PostSharp4EF
{
    /// <summary>
    /// this interface is implemented on all your domainclasses. It exposes a way to load relationships.
    /// </summary>
    /// <remarks>since it is implemented during postcompiliation, your IDE does not know your domainclasses implement it. Therefor
    /// you will need to cast to it.
    /// Use Postsharp.Post.Cast to check these casts at compile time
    /// </remarks>
    /// <example>
    /// 	<![CDATA[
    /// Customer c = new Customer();
    /// IRelationshipLoader noLazyLoading = PostSharp.Post.Cast<Customer, IRelationshipLoader>(c);
    /// ]]></example>
	public interface IRelationshipLoader
	{
        /// <summary>
        /// Loads a relationship
        /// </summary>
        /// <param name="PropertyName">Name of the property pointing to your relation.</param>
        /// <remarks>will use a mergeoption of 'preserveChanges'</remarks>
        void Load(string PropertyName);

        /// <summary>
        /// Loads the specified relation name.
        /// </summary>
        /// <param name="PropertyName">Name of the property pointing to your relation.</param>
        /// <param name="mergeOption">The merge option.</param>
        void Load(string PropertyName, MergeOption mergeOption);

        /// <summary>
        /// Determines whether the specified relationship is loaded.
        /// </summary>
        /// <param name="PropertyName">Name of the property pointing to your relation.</param>
        /// <returns>
        /// 	<c>true</c> if the specified property name is loaded; otherwise, <c>false</c>.
        /// </returns>
        bool IsLoaded(string PropertyName);

        /// <summary>
        /// Gets the related end.
        /// </summary>
        /// <param name="PropertyName">Name of the property.</param>
        /// <returns>IRelatedEnd</returns>
        /// <remarks>by using this method, your code will rely on EF specific implementations.
        /// Try to use more generic methods, like Load and IsLoaded, which are quite generic</remarks>
        IRelatedEnd GetRelatedEnd(string PropertyName);

        /// <summary>
        /// Gets the related collection.
        /// </summary>
        /// <typeparam name="T">the type of the instances in the collection</typeparam>
        /// <param name="PropertyName">Name of the property.</param>
        /// <returns></returns>
        EntityCollection<T> GetRelatedCollection<T>(string PropertyName)
            where T : class, IEntityWithRelationships;


        /// <summary>
        /// Gets the related reference.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="PropertyName">Name of the property.</param>
        /// <returns></returns>
        EntityReference<T> GetRelatedReference<T>(string PropertyName)
            where T : class, IEntityWithRelationships;
	}


}
